import { usePlayerStore } from '@/stores/modules/player'
import { useGameStore } from '@/stores/modules/game'

import type { IChef } from '@/stores/types'

export interface IChefAndCollect {
  chef: IChef
  collect: {
    veg: number
    fish: number
    creation: number
    meat: number
  }
}

type CollectType = 'fish' | 'creation' | 'meat' | 'veg'

const SPOT_NAME_MAP = new Map<string, CollectType[]>(
  Object.entries({
    森林: ['veg'],
    菜地: ['veg'],
    池塘: ['fish'],
    作坊: ['creation'],
    牧场: ['meat'],
    菜棚: ['veg'],
    鸡舍: ['meat'],
    猪圈: ['meat'],
    朝阴山: ['meat', 'creation'],
    永昼宫: ['veg', 'fish'],
    还寒洞: ['veg', 'creation'],
    北冥城: ['fish', 'creation'],
    藏心亭: ['meat', 'veg'],
    清空谷: ['meat', 'fish'],
  }),
)

export function getComputeGroup(spotName: string, total: number, limit = 5) {
  const collect = SPOT_NAME_MAP.get(spotName)
  if (!collect) return null

  cleanSpotChefs(spotName)

  const freeChefs: IChefAndCollect[] = []
  usePlayerStore().freeChefs.forEach((chef) => {
    const chefInfo = useGameStore().chefsMap.get(chef.id)
    if (!chefInfo) return
    const collectSkill = usePlayerStore().getChefCollectingSkills(chef.id)
    if (!collectSkill) return
    freeChefs.push({
      chef: chefInfo,
      collect: collectSkill,
    })
  })

  const remainingChefs = freeChefs.filter((f) => collect.every((e) => f.collect[e]))
  remainingChefs.sort((a, b) => {
    const skillA = collect.reduce((acc, cur) => acc + a.collect[cur], 0) || 0
    const skillB = collect.reduce((acc, cur) => acc + b.collect[cur], 0) || 0
    if (skillB === skillA) {
      return b.chef.rarity - a.chef.rarity
    }
    return skillB - skillA
  })

  // 初始化分配团队，最多取 limit 个厨师
  const currentTeam = remainingChefs.splice(0, limit)
  // 计算团队技能总值
  const calcTeamSkillSum = () =>
    currentTeam.reduce(
      (acc, cur) => acc + collect.reduce((stAcc, stCur) => stAcc + cur.collect[stCur], 0),
      0,
    )

  let previousTeam: IChefAndCollect[] = []

  // 技能点总数要大于等于 total
  // 循环次数不能超出等待分配厨师的数量
  while (calcTeamSkillSum() >= total && remainingChefs.length) {
    // 从分配团队中筛选稀有度最高、技能数最高的厨师
    const mostRarityIndex = currentTeam.reduce((mostIndex, currentItem, currentIndex, array) => {
      if (currentItem.chef.rarity > array[mostIndex].chef.rarity) {
        return currentIndex
      }
      return mostIndex
    }, 0)

    // 从等待分配厨师队伍获取一个，替代稀有度最高、技能数最高的厨师
    const nextChef = remainingChefs.shift()
    if (nextChef) {
      // 备份上一次厨师数据
      previousTeam = [...currentTeam]
      currentTeam.splice(mostRarityIndex, 1, nextChef)
    }
  }

  // 给厨师打上工作标记
  previousTeam.forEach(({ chef }) => {
    usePlayerStore().setWorkingChef({
      name: chef.name,
      id: chef.chefId,
      pos: spotName,
    })
  })

  return previousTeam
}

/**
 * 移除资源点中工作的厨师
 * @param spotName 资源点名称
 */
export function cleanSpotChefs(spotName: string) {
  const { workingChefs, removeWorkingChef } = usePlayerStore()
  workingChefs
    .filter((f) => f.pos === spotName)
    .forEach((chef) => {
      removeWorkingChef(chef.id)
    })
}
